package service

import (
	"context"
	"fmt"
	"io/ioutil"
	"time"

	"github.com/google/uuid"
	"go.uber.org/zap"
	"go-file-perception-model/internal/config"
	"go-file-perception-model/internal/logger"
	"go-file-perception-model/internal/model"
)

// FileProcessor 文件处理器 - 重构后的简化版本
type FileProcessor struct {
	embeddingModel      EmbeddingModel
	config             *config.FileIndexConfig
	enhancedChunker    *EnhancedTextChunker
	textEncoder        *TextEncoder
	positionCalculator *PositionCalculator
	contentUtils       *ContentUtils
}

// NewFileProcessor 创建文件处理器实例
func NewFileProcessor(embeddingModel EmbeddingModel, cfg *config.FileIndexConfig) *FileProcessor {
	return &FileProcessor{
		embeddingModel:      embeddingModel,
		config:             cfg,
		enhancedChunker:    NewEnhancedTextChunker(embeddingModel, cfg),
		textEncoder:        NewTextEncoder(),
		positionCalculator: NewPositionCalculator(cfg),
		contentUtils:       NewContentUtils(),
	}
}

// ProcessFile 处理单个文件 - 重构后的简化版本
func (p *FileProcessor) ProcessFile(filePath string) ([]*model.FileChunk, error) {
	// 读取文件内容
	content, err := ioutil.ReadFile(filePath)
	if err != nil {
		return nil, fmt.Errorf("failed to read file: %w", err)
	}

	// 转换为字符串，确保UTF-8编码
	text := p.textEncoder.EnsureUTF8(content)

	// 使用增强的文本分块器进行分块
	chunks, err := p.enhancedChunker.ChunkText(text)
	if err != nil {
		logger.Error("Failed to chunk text with enhanced chunker", zap.String("file", filePath), zap.Error(err))
		return nil, fmt.Errorf("failed to chunk text: %w", err)
	}

	// 计算分块位置
	isSemanticChunking := p.config.SemanticChunking
	chunkPositions := p.positionCalculator.CalculateChunkPositions(text, chunks, isSemanticChunking)

	// 处理每个分块
	var fileChunks []*model.FileChunk
	for i, chunkText := range chunks {
		if i >= len(chunkPositions) {
			logger.Error("Chunk position not found", zap.Int("chunk_index", i))
			continue
		}
		
		pos := chunkPositions[i]
		
		// 创建分块模型
		chunk := &model.FileChunk{
			ID:        uuid.New().String(),
			FileID:    uuid.New().String(),
			FilePath:  filePath,
			Content:   chunkText,
			ChunkNo:   i + 1,
			StartPos:  pos.StartPos,
			EndPos:    pos.EndPos,
			StartLine: p.positionCalculator.CalculateLineNumber(text, pos.StartPos),
			EndLine:   p.positionCalculator.CalculateLineNumber(text, pos.EndPos-1),
			CreatedAt: time.Now(),
			UpdatedAt: time.Now(),
		}

		// 获取嵌入向量
		if p.embeddingModel != nil {
			vector, err := p.embeddingModel.Embedding(context.Background(), chunkText)
			if err != nil {
				logger.Error("Failed to get embedding for chunk", zap.Int("chunk", i), zap.Error(err))
				continue
			}
			chunk.Vector = vector
		}

		fileChunks = append(fileChunks, chunk)
	}

	logger.Info("File processed successfully", zap.String("file", filePath), zap.Int("chunks", len(fileChunks)))
	return fileChunks, nil
}

// GenerateSummary 生成文本摘要
func (p *FileProcessor) GenerateSummary(text string) (string, error) {
	return p.contentUtils.GenerateSummary(text, p.config.SummaryLength), nil
}

// GetContentType 获取内容类型
func (p *FileProcessor) GetContentType(filePath string) string {
	return p.contentUtils.GetContentType(filePath)
}